﻿// ===============================================================================
// Project Name        :	Weisenz.Core
// Project Description :	Weisenz系统核心类库。
// ===============================================================================
// Class Name          :	StringUtil
// Class Version       :	v1.0.0.0
// Class Description   :	字符相关操作静态类。
// Author              :	Charles
// Create Time         :	2012/3/29 
// Update Time         :	2012/3/29 
// ===============================================================================
// Copyright © Weisenz 2012 . All rights reserved.
// ===============================================================================
using System;
using System.Collections;
using System.Configuration;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Security;

namespace Weisenz.Core
{
    /// <summary>
    /// 字符相关操作静态类。
    /// </summary>
    public static class StringUtil
    {
        private const string RandomStringSource = "";

        /// <summary>
        /// 将明文加密为系统字符。
        /// </summary>
        /// <param name="str">即将加密的明文字符。</param>
        /// <returns>加密后的字符串。</returns>
        public static string Encryption(string str)
        {
            if (!string.IsNullOrEmpty(str))
            {
                str = FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5");
                if (str != null) str = FormsAuthentication.HashPasswordForStoringInConfigFile(str, "SHA1");
            }
            return str;
        }

        /// <summary>
        /// 取得Gravatar的MD5。
        /// </summary>
        /// <param name="email">邮件地址。</param>
        /// <returns>返回Gravatar用MD5值。</returns>
        public static string GravatarID(string email)
        {
            string result = string.Empty;
            if (!string.IsNullOrEmpty(email))
            {
                var hashPasswordForStoringInConfigFile = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(email, "MD5");
                if (hashPasswordForStoringInConfigFile != null)
                    result = hashPasswordForStoringInConfigFile.ToLower();
            }
            return result;
        }

        /// <summary>
        /// 对字符串进行 HTML 编码并返回已编码的字符串。
        /// </summary>
        /// <param name="str">要编码的文本字符串。</param>
        /// <returns>返回已编码的字符串。</returns>
        public static string HtmlEncode(string str)
        {
            if (!string.IsNullOrEmpty(str))
            {
                str = HttpContext.Current.Server.HtmlEncode(str);
            }
            return str;
        }

        /// <summary>
        /// 对文件大小进行格式化。
        /// </summary>
        /// <param name="len">文件大小。</param>
        /// <returns>返回格式化的字符串。</returns>
        public static string FormatLength(long len)
        {
            if (len > 0x40000000)
            {
                return string.Format("{0} GB", ObjectToInt(len / 0x40000000));
            }
            if (len > 0x00100000)
            {
                return string.Format("{0} MB", ObjectToInt(len / 0x00100000));
            }
            if (len > 0x00000400)
            {
                return string.Format("{0} KB", ObjectToInt(len / 0x00000400));
            }
            return string.Format("{0} byte", ObjectToInt(len));
        }

        /// <summary>
        /// 对URL地址进行格式化。
        /// </summary>
        /// <param name="url">需要格式化的URL地址。</param>
        /// <returns>返回格式化的地址。</returns>
        public static string FormatUrl(string url)
        {
            if (!string.IsNullOrEmpty(url))
            {
                if (!Regex.IsMatch(url, @"^\w{3,6}:\/\/.*$", RegexOptions.IgnoreCase))
                {
                    url = "http://" + url;
                }
            }
            return url;
        }

        /// <summary>
        /// 生成指定长度的随机字符串。
        /// </summary>
        /// <param name="length">要生成的字符串长度。</param>
        /// <returns>返回生成的字符串。</returns>
        private static string RandomString(int length)
        {
            //随机数种子
            Random random = new Random();
            int number = random.Next();
            return number.ToString().Substring(0, length);
        }


        /// <summary>
        /// 清除字符串中的 HTML 标签。
        /// </summary>
        /// <param name="html">原始代码</param>
        /// <returns>返回纯文本</returns>
        public static string ClearHtml(string html)
        {
            if (!string.IsNullOrEmpty(html))
            {
                html = Regex.Replace(html, @"<[^>]*>", string.Empty);
            }
            return html;
        }

        /// <summary>
        /// 对指定字符串进行 URL 解码。
        /// </summary>
        /// <param name="str">需要解码的字符串。</param>
        /// <returns>返回解码的字符串。</returns>
        public static string UrlDecode(string str)
        {
            if (!string.IsNullOrEmpty(str))
            {
                str = HttpUtility.UrlDecode(str, Encoding.UTF8);
            }
            return str;
        }

        /// <summary>
        /// 对指定字符串进行 URL 编码。
        /// </summary>
        /// <param name="str">需要编码的字符串。</param>
        /// <returns>返回编码的字符串。</returns>
        public static string UrlEncode(string str)
        {
            if (!string.IsNullOrEmpty(str))
            {
                str = HttpUtility.UrlEncode(str, Encoding.UTF8);
            }
            return str;
        }


        /// <summary>
        /// 将对象转换为数字类型（错误兼容）。
        /// </summary>
        /// <param name="obj">需要转换的对象。</param>
        /// <returns>返回转换的类型。</returns>
        public static int ObjectToInt(object obj)
        {
            int result = int.TryParse(obj.ToString(), out result) ? result : 0;
            return result;
        }

        /// <summary>
        /// 将对象转换为日期类型（错误兼容）。
        /// </summary>
        /// <param name="obj">需要转换的对象。</param>
        /// <returns>返回转换的类型。</returns>
        public static DateTime ObjectToDate(object obj)
        {
            DateTime result = DateTime.TryParse(obj.ToString(), out result) ? result : DateTime.Now;
            return result;
        }

        /// <summary>
        /// 将对象转换为布尔类型（错误兼容）。
        /// </summary>
        /// <param name="obj">需要转换的对象。</param>
        /// <returns>返回转换的类型。</returns>
        public static bool ObjectToBool(object obj)
        {
            bool result = bool.TryParse(obj.ToString(), out result) && result;
            return result;
        }

        /// <summary>
        /// 转换字符串到数据库可输入模式。
        /// </summary>
        /// <param name="src">待插入数据库的字符串。</param>
        /// <returns>可插入数据库的字符串。</returns>
        public static string StringToSql(string src)
        {
            if (src == null)
            {
                return null;
            }
            return Replace(src, "'", "''");
        }

        /// <summary>
        /// 判断是否是合法的永久文件名。
        /// </summary>
        /// <param name="fileName">文件名。</param>
        /// <returns>返回校验结果。</returns>
        public static bool IsLawful(string fileName)
        {
            bool result = false;
            if (!string.IsNullOrEmpty(fileName))
            {
                result = Regex.IsMatch(fileName, @"^[^\d]+[\w\-]*");
            }
            return result;
        }

        /// <summary>
        /// 截取字符串。
        /// </summary>
        /// <param name="str">字符串。</param>
        /// <param name="len">截取的长度。</param>
        /// <returns>返回截取后的字符串。</returns>
        public static string CutString(string str, int len)
        {
            if (!string.IsNullOrEmpty(str) && len > 0)
            {
                int l = str.Length;
                int clen = 0;
                while (clen < len && clen < l)
                {
                    //每次遇到一个中文，则将该长度减一   
                    if (str[clen] > 128) { len--; }
                    clen++;
                }
                if (clen < l && clen > 2) { str = str.Substring(0, clen - 2) + ".."; }
            }
            return str;
        }

        /// <summary>
        /// 处理原本格式并进行HTML编码
        /// </summary>
        /// <param name="text">原始文本</param>
        /// <returns>返回处理后的代码</returns>
        public static string Pre(string text)
        {
            if (!string.IsNullOrEmpty(text))
            {
                text = HtmlEncode(text).Replace("\n", "<br/>");
            }
            return text;
        }

        /// <summary>
        /// 在指定的输入字符串内，使用指定的替换字符串替换与某个正则表达式模式匹配的所有字符串。
        /// </summary>
        /// <param name="src">要修改的字符串。</param>
        /// <param name="pattern">要匹配的正则表达式模式。</param>
        /// <param name="replacement">替换字符串。</param>
        /// <param name="options">匹配模式。</param>
        /// <returns>已修改的字符串。</returns>
        public static string Replace(string src, string pattern, string replacement, RegexOptions options)
        {
            Regex regex = new Regex(pattern, options | RegexOptions.Compiled);
            return regex.Replace(src, replacement);
        }

        /// <summary>
        /// 替换字符串
        /// </summary>
        /// <param name="src">要修改的字符串。</param>
        /// <param name="pattern">要匹配的正则表达式模式。</param>
        /// <param name="replacement">替换字符串。</param>
        /// <returns>已修改的字符串</returns>
        public static string Replace(string src, string pattern, string replacement)
        {
            return Replace(src, pattern, replacement, RegexOptions.None);
        }


        /// <summary>
        /// 替换字符串，不区分大小写。
        /// </summary>
        /// <param name="src">要修改的字符串。</param>
        /// <param name="pattern">要匹配的正则表达式模式。</param>
        /// <param name="replacement">替换字符串。</param>
        /// <returns>已修改的字符串。</returns>
        public static string ReplaceString(string src, string pattern, string replacement)
        {
            return Replace(src, pattern, replacement, RegexOptions.IgnoreCase);
        }

        /// <summary>
        /// 检查字符串是否符合Sql 安全标准，如果符合则直接返回，否则剔出不安全因素。
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string GetSafeString(string str)
        {
            if (str == null)
            { return null; }
            else
            {
                string rs = str.Replace("'", "");
                return rs;
            }
        }

        /// <summary>
        /// 删除字符串中指定的内容，不区分大小写。
        /// </summary>
        /// <param name="src">要修改的字符串</param>
        /// <param name="pattern">要删除的正则表达式模式</param>
        /// <returns>已删除指定内容的字符串</returns>
        public static string DropString(string src, string pattern)
        {
            return ReplaceString(src, pattern, "");
        }

        /// <summary>
        /// 去掉html内容中的指定的html标签。
        /// </summary>
        /// <param name="content">html内容。</param>
        /// <param name="tagName">html标签。</param>
        /// <returns>去掉标签的内容。</returns>
        public static string DropHtmlTag(string content, string tagName)
        {
            //去掉<tagname>和</tagname>
            return DropString(content, "<[/]{0,1}" + tagName + "[^\\>]*\\>");
        }

        /// <summary>
        /// 标签配对格式化
        /// </summary>
        /// <param name="html">要配对的内容。</param>
        /// <returns>不缺失的HTML内容。</returns>
        public static string HtmlMatch(string html)
        {
            string result = html;
            if (result.Length > 0)
            {
                MatchCollection matchs = Regex.Matches(html, @"<([^\s>\/]+)(|\s[^>]+)>", RegexOptions.IgnoreCase | RegexOptions.RightToLeft);
                ArrayList tabs = new ArrayList();
                foreach (Match match in matchs)
                {
                    string tab = match.Groups[1].Value.ToLower();
                    if (tab.Length > 0 && !tabs.Contains(tab))
                    {
                        if (tab != "hr" && tab != "br" && tab != "img")
                        {
                            tabs.Add(tab);
                        }
                    }
                }
                //string[] tabs = { "P", "TABLE", "", "", "", "", "", "UL", "OL", "DIV", "H1", "H2", "H3", "H4", "H5", "H6" };
                foreach (string tab in tabs)
                {
                    int tabNum = Regex.Matches(html, string.Format(@"<{0}(|\s[^>]+)>", tab), RegexOptions.IgnoreCase).Count;
                    int endTabNum = Regex.Matches(html, string.Format(@"<\/{0}>", tab), RegexOptions.IgnoreCase).Count;
                    if (tabNum > 0)
                    {
                        int outNum = tabNum - endTabNum;
                        if (outNum > 0)
                        {
                            for (int i = 0; i < outNum; i++)
                            {
                                result += string.Format("</{0}>", tab);
                            }
                        }
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 读取 Web.Config 中的键值。
        /// </summary>
        /// <param name="key">键名。</param>
        /// <returns>键值。</returns>
        public static string GetSettingValue(string key)
        {
            return ConfigurationManager.AppSettings[key].ToString();
        }

        /// <summary>
        /// 过滤 sql 中的不安全字符。
        /// </summary>
        /// <param name="str">初始状态的 sql 语句。</param>
        /// <returns>过滤后的 sql 语句。</returns>
        public static string SqlFix(string str)
        {
            string result = "";

            if (!String.IsNullOrEmpty(str))
            {
                result = str.Replace("'", "");
                result = result.Replace(";", "；");
                result = result.Replace("(", "（");
                result = result.Replace(")", "）");
                result = result.Replace("[", "");
                result = result.Replace("]", "");
                result = result.Replace("&", "");
                result = result.Replace("%", "");
                result = result.Replace("<", "");
                result = result.Replace(">", "");
                result = result.Replace("+", "");
                result = result.Replace("--", "");
                result = result.Replace("/*", "");
                result = result.Replace("*/", "");
                result = result.Replace("|", "");
                string pattern = @"delete|drop|insert|select|update|from|grant|alter|count\(|create|backup|truncate|exec|\<script|\</script\>|script|javascript|jscript|vbscript|xp_regread|hkey_local|declare|char\(|xp_cmdshell";
                result = Regex.Replace(result, pattern, "", RegexOptions.IgnoreCase);
            }

            return result;
        }

        /// <summary>
        /// 把指定的字符串转换成 SQL 编码。
        /// </summary>
        /// <param name="str">指定的字符串。</param>
        /// <returns>返回转换之后的字符串。</returns>
        public static string SqlEncode(string str)
        {
            if (!string.IsNullOrEmpty(str))
            {
                str = str.Replace("'", "&#39;");
                str = HttpContext.Current.Server.HtmlEncode(str);
            }
            return str;
        }
    }
}
